#include "bsp_i2c.h"
bsp_i2c_msg_t g_i2c_msg;
bsp_i2c_init_t *handle_I2C = NULL;
uint8_t I2C1_txbuf[TX_LEN],I2C1_rxbuf[RX_LEN];
int32_t BSP_I2C_Init(bsp_i2c_init_t *pI2CInit)
{
    uint32_t pclkfreq = HAL_SysCtrl_GetPclkFreq();
    HAL_SYSCTRL_I2C1_CLK_ENABLE();
    SYM_SYSCTRL->APBRST2_f.I2C1 = 0;
    SYM_SYSCTRL->APBRST2_f.I2C1 = 1;
    SYM_I2C1->CR    = 0;
    SYM_I2C1->BRR   = pclkfreq / 8 / pI2CInit->baudrate - 1;
    if(pI2CInit->i2c_mode == I2C_MD_SLAVE) // 从机模式
    {
        SYM_I2C1->ADDR0 = pI2CInit->slaveaddr1;
        SYM_I2C1->ADDR1 = pI2CInit->slaveaddr2;
        SYM_I2C1->ADDR2 = pI2CInit->slaveaddr3;
        if(SYM_I2C1->BRR <= 4)        // fpclk / fscl <= 40
        {
            SYM_I2C1->CR |= I2Cx_CR_FLT_Msk;
        }
    }
    else // 主机模式
    {
        SYM_I2C1->BRREN = 0x01;
        if(SYM_I2C1->BRR <= 9)
        {
            SYM_I2C1->CR |= I2Cx_CR_FLT_Msk;
        }

    }
    bsp_gpio_init(pI2CInit->gpio_scl);
    bsp_gpio_init(pI2CInit->gpio_sda);
    /*enable NVIC intterupt */
    NVIC_ClearPendingIRQ(I2C1_IRQn);
    NVIC_EnableIRQ(I2C1_IRQn);
    SYM_I2C1->CR_f.EN = 1;
    handle_I2C = pI2CInit; 
    return 0;
}

int32_t BSP_I2C_DeInit(bsp_i2c_init_t *pI2CInit)
{
    SYM_SYSCTRL->APBRST2_f.I2C1 = 0;
    SYM_SYSCTRL->APBRST2_f.I2C1 = 1;
    HAL_SYSCTRL_I2C1_CLK_DISABLE();
    return 0;
}
void BSP_I2C_Reconfig(void)
{
    
    BSP_I2C_DeInit(handle_I2C);
    BSP_I2C_Init(handle_I2C);
}
void BSP_I2C_Int_Callback(void)
{
    volatile uint8_t u8state = SYM_I2C1->STAT_f.STAT; 
    switch (u8state)
    {
    case MASTER_I2C_START:
        SYM_I2C1->CR_f.STA = 0;
        SYM_I2C1->DR_f.DR = g_i2c_msg.devAddr<< 1 & 0xFE;
        break;
    case MASTER_I2C_RESTART:
        SYM_I2C1->CR_f.STA = 0;
        if(g_i2c_msg.RW == I2C_WRITE){
            SYM_I2C1->DR_f.DR = g_i2c_msg.devAddr<< 1 & 0xFE;//写地址 Write Address
        }
        else{
            SYM_I2C1->DR_f.DR = g_i2c_msg.devAddr<< 1 | 0x01;//读地址 Read Address
        }
        break;
    case MASTER_I2C_WR_DEVADDR_ACK:
        SYM_I2C1->CR_f.STA = 0;
        if(g_i2c_msg.reglen > 0){
            SYM_I2C1->DR_f.DR = g_i2c_msg.preg[g_i2c_msg.regcnt];
            g_i2c_msg.regcnt++;
        }
        else{
            if(g_i2c_msg.len > 0){
                SYM_I2C1->DR_f.DR = g_i2c_msg.pdata[g_i2c_msg.txcnt];
                g_i2c_msg.txcnt++;
            }
            else{
                SYM_I2C1->CR_f.STO = 1;
            }
        }
        break;
    case MASTER_I2C_WR_DEVADDR_NAK:
    case MASTER_ARBITRATION_LOST:
    case MASTER_I2C_WR_DR_NAK:
    case MASTER_I2C_RD_DEVADDR_NAK:
//        SYM_I2C1->CR_f.STA = 1;
        SYM_I2C1->CR_f.STO = 1;
        break;
    case MASTER_I2C_RD_DR_NAK:
        g_i2c_msg.pdata[g_i2c_msg.rxcnt] = 0;
        g_i2c_msg.rxcnt++;
        SYM_I2C1->CR_f.STO = 1;
        break;
    case MASTER_I2C_WR_DR_ACK:
        if(g_i2c_msg.reglen > g_i2c_msg.regcnt){
             SYM_I2C1->DR_f.DR = g_i2c_msg.preg[g_i2c_msg.regcnt];
            g_i2c_msg.regcnt++;
        }else{
            if(g_i2c_msg.RW == I2C_WRITE){
                if(g_i2c_msg.len > g_i2c_msg.txcnt){
                    SYM_I2C1->DR_f.DR = g_i2c_msg.pdata[g_i2c_msg.txcnt];
                    g_i2c_msg.txcnt++;
                }
            }else{
                SYM_I2C1->CR_f.STA = 1;//Generate Restart
                SYM_I2C1->CR_f.STO = 0;
            }
        }
        break;
    case MASTER_I2C_RD_DEVADDR_ACK:
        SYM_I2C1->CR_f.AA = I2C_AA_ACK;
        break;
    case MASTER_I2C_RD_DR_ACK:
        g_i2c_msg.pdata[g_i2c_msg.rxcnt] = SYM_I2C1->DR_f.DR;
        g_i2c_msg.rxcnt++;
        if(g_i2c_msg.rxcnt == g_i2c_msg.len - 1){
            SYM_I2C1->CR_f.AA = I2C_AA_NAK;
        }
    default:
        BSP_I2C_Reconfig();
        break;
    } 
    SYM_I2C1->CR_f.SI = 0;   
}
int32_t BSP_I2C_Write(bsp_i2c_init_t *pI2CInit, uint8_t devAddr, uint8_t *preg, uint8_t reglen, uint8_t *pdata, uint16_t len)
{
//    uint16_t i;
    g_i2c_msg.devAddr = devAddr;
    g_i2c_msg.pdata = pdata;
    g_i2c_msg.preg = preg;
    g_i2c_msg.reglen = reglen;
    g_i2c_msg.len = len;
    g_i2c_msg.RW = I2C_WRITE;
    g_i2c_msg.txcnt = 0;
    g_i2c_msg.rxcnt = 0;
    g_i2c_msg.regcnt = 0;
    SYM_I2C1->CR_f.STA = 1;//发送START,启动I2C时序
    return 0;
}

int32_t BSP_I2C_Read(bsp_i2c_init_t *pI2CInit, uint8_t devAddr, uint8_t *preg, uint8_t reglen, uint8_t *pdata, uint16_t len)
{
    g_i2c_msg.devAddr = devAddr;
    g_i2c_msg.pdata = pdata;
    g_i2c_msg.preg = preg;
    g_i2c_msg.reglen = reglen;
    g_i2c_msg.len = len;
    g_i2c_msg.RW = I2C_READ;
    g_i2c_msg.txcnt = 0;
    g_i2c_msg.rxcnt = 0;
    g_i2c_msg.regcnt = 0;
    SYM_I2C1->CR_f.STA = 1;//发送START,启动I2C时序
    return 0;
}

// int32_t BSP_I2C_IsDeviceReady(bsp_i2c_init_t *pI2CInit, uint8_t devAddr, uint32_t timeout)
// {
//     return 0;
// }


